package cn.numeron.wxarticle.impl.list

import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.paging.CombinedLoadStates
import androidx.paging.LoadState
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.RecyclerView
import cn.numeron.common.State
import cn.numeron.common.view.PagingRetryAdapter
import cn.numeron.common.viewbinding.viewBinding
import cn.numeron.recyclerview.adapter.PagingAutomaticBindingAdapter
import cn.numeron.sliderefreshlayout.SlideRefreshLayout
import cn.numeron.wxarticle.api.wxarticle.WxArticle
import cn.numeron.wxarticle.impl.R
import cn.numeron.wxarticle.impl.databinding.FragmentWxArticleListBinding
import cn.numeron.wxarticle.impl.databinding.RecyclerItemWxArticleBinding
import cn.numeron.wxarticle.impl.wxarticle.WxArticleViewModel
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch

@AndroidEntryPoint
class WxArticleListFragment : Fragment(R.layout.fragment_wx_article_list) {

    private val listeners = Listeners()

    private val navController by lazy(::findNavController)

    private val wxArticleViewModel: WxArticleViewModel by viewModels()

    private val viewBinding: FragmentWxArticleListBinding by viewBinding()

    private val wxArticleAdapter = WxArticleAdapter()

    private inner class WxArticleAdapter :
        PagingAutomaticBindingAdapter<WxArticle, RecyclerItemWxArticleBinding>()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewBinding.wxArticleRecyclerView.adapter = wxArticleAdapter
            .withLoadStateFooter(PagingRetryAdapter(wxArticleAdapter::retry))
        viewBinding.wxArticleRecyclerView.addItemDecoration(
            DividerItemDecoration(
                view.context,
                RecyclerView.VERTICAL
            )
        )

        viewBinding.wxArticleRefreshLayout.onRefreshListener = listeners
        viewBinding.wxArticleKeywordEditText.addTextChangedListener(listeners)

        wxArticleAdapter.addLoadStateListener(listeners::onLoadStateChanged)
        wxArticleAdapter.clickItemEvent.observe(viewLifecycleOwner, ::onWxArticleClick)

        viewLifecycleOwner.lifecycleScope.launch {
            wxArticleViewModel.wxArticleStatefulLiveData.collectLatest(wxArticleAdapter::submitData)
        }

    }

    private fun onWxArticleClick(wxArticle: WxArticle) {
        navController.navigate(R.id.action_to_wx_article_graph)
    }

    private inner class Listeners : SlideRefreshLayout.OnRefreshListener, TextWatcher {

        override fun onRefresh() = wxArticleAdapter.refresh()

        fun onLoadStateChanged(state: CombinedLoadStates) {
            //取出刷新状态
            when (val refresh = state.refresh) {
                is LoadState.NotLoading -> {
                    //当未加载时，停止刷新，并且根据是否有数据，决定显示哪个状态视图
                    if (viewBinding.wxArticleRefreshLayout.isRefresh) {
                        viewBinding.wxArticleRefreshLayout.restoreDelay(1000, "刷新成功")
                    }
                    viewBinding.wxArticleStatefulLayout.state =
                        if (wxArticleAdapter.itemCount == 0) State.Empty else State.Success
                }
                is LoadState.Loading -> {
                    //当正在加载时，根据是否有数据，决定显示加载状态的视图，还是只是弹出顶部的加载视图
                    if (wxArticleAdapter.itemCount == 0) {
                        viewBinding.wxArticleStatefulLayout.state = State.Loading
                    } else {
                        viewBinding.wxArticleRefreshLayout.isRefresh = true
                    }
                }
                is LoadState.Error -> {
                    viewBinding.wxArticleStatefulLayout.state =
                        if (wxArticleAdapter.itemCount == 0) State.Failure else State.Success
                    refresh.error.printStackTrace()
                }
            }
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

        }

        override fun afterTextChanged(s: Editable?) {
            wxArticleViewModel.keyword = s?.toString()
        }

    }

    companion object {

        private const val TAG = "WxArticleListFragment"

    }

}